package com.itianyu.blog.web.controller;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.ClassEditor;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.itianyu.blog.dao.beans.Entry;
import com.itianyu.blog.dao.beans.Tag;
import com.itianyu.blog.dao.beans.User;
import com.itianyu.blog.dao.interfaces.EntryInterface;
import com.itianyu.blog.dao.interfaces.TagInterface;
import com.itianyu.blog.dao.interfaces.UserInterface;
import com.itianyu.blog.validation.EntryValidator;

/**
 * 博文控制层
 * @author wumgji
 */
@Controller
@RequestMapping("/entry")
public class EntryController {

	@Autowired
	private EntryInterface entryInterface;

	@Autowired
	private TagInterface tagInterface;

	@Autowired
	private UserInterface userInterface;

	@Autowired
	private EntryValidator entryValidator; // 博文表单验证

	// 绑定表单数据，转化Spring不能直接处理的数据
	@InitBinder
	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder dataBinder) throws Exception {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
		df.setLenient(false);
		dataBinder.registerCustomEditor(Date.class, "creationDate", new CustomDateEditor(df, false));

		dataBinder.registerCustomEditor(User.class, new ClassEditor() {
			public void setAsText(String text) {
				setValue(userInterface.findUser(text));
			}
		});

		dataBinder.registerCustomEditor(Tag.class, new ClassEditor() {
			public void setAsText(String text) {
				setValue(tagInterface.findTagByName(text));
			}
		});
	}

	// 根据博文ID编辑博文信息
	@RequestMapping(value = "/{entryid}/edit", method = RequestMethod.GET)
	public ModelAndView editEntry(@PathVariable("entryid") int entryid) {
		if (entryid == 0) { // 如果entryid为0，新增博文
			Entry entry = entryInterface.createEntry();

			entry.setCreationDate(new Date());

			entry.setUser((User) ((SecurityContext) SecurityContextHolder.getContext()).getAuthentication().getPrincipal());

			return new ModelAndView("entryform", new ModelMap().addAttribute("entry", entry));
		} else { // 如果entryid不为0，编辑博文然后跳转
			Entry entry = entryInterface.findEntry(entryid);
			return new ModelAndView("entryform", new ModelMap().addAttribute("entry", entry));
		}
	}

	// 保存博文信息（entryid参数作用仅是保持url一致性）
	@RequestMapping(value = "/{entryid}/save", method = RequestMethod.POST)
	public ModelAndView saveEntry(@PathVariable("entryid") int entryid, @ModelAttribute("entry") Entry entry, BindingResult result) {
		entry.setModificationDate(new Date());
		entry.setCommenttotal(0);
		entryValidator.validate(entry, result);
		if (result.hasErrors()) {
			// 加载验证错误信息，然后返回表单
			return new ModelAndView("entryform");
		} else {
			entry = entryInterface.saveEntry(entry);
			// redirect避免重复提交
			return new ModelAndView("redirect:/app/entry/" + entry.getEntryId());
		}
	}

	// 根据博文ID删除博文信息
	@RequestMapping(value = "/{entryid}/delete", method = RequestMethod.GET)
	public String deleteEntry(@PathVariable("entryid") int entryid) {
		entryInterface.deleteEntry(entryid);
		return "redirect:/app/entries";
	}

	// 发布博文
	@RequestMapping(value = "/{entryid}/publish", method = RequestMethod.GET)
	public String publishEntry(@PathVariable("entryid") int entryid) {
		Entry entry = entryInterface.findEntry(entryid);
		entry.setPublished(true);
		entryInterface.saveEntry(entry);

		return "redirect:/app/entries/unpublished";
	}

	// 取消发布博文
	@RequestMapping(value = "/{entryid}/unpublish", method = RequestMethod.GET)
	public String unpublishEntry(@PathVariable("entryid") int entryid) {
		Entry entry = entryInterface.findEntry(entryid);
		entry.setPublished(false);
		entryInterface.saveEntry(entry);

		return "redirect:/app/entries";
	}

	// 查询博文信息
	@RequestMapping(value = "/{entryid}", method = RequestMethod.GET)
	public ModelAndView showEntry(@PathVariable("entryid") int entryid) {
		List<Entry> entries = new ArrayList<Entry>();

		if (entryInterface.findEntry(entryid) != null) {

			// 核对是否有ROLE_ADMIN权限
			boolean admin_role = false;

			// 如果未认证，getPrincipal()返回游客权限；如果已认证，getPrincipal()返回后台管理用户权限
			Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
			if (authentication != null && authentication.getPrincipal() != null && authentication.getPrincipal().getClass().equals(User.class) && ((User) authentication.getPrincipal()).getAuthorities() != null) {
				for (int i = 0; i < ((User) authentication.getPrincipal()).getAuthorities().size(); i++) {
					if (((User) authentication.getPrincipal()).getAuthorities().get(i).getAuthority().compareToIgnoreCase("ROLE_ADMIN") == 0) {
						admin_role = true;
						break;
					}
				}
			}

			// 前台展示显示全部已发布博文，后台管理显示ROLE_ADMIN角色对应的未发布博文
			if (entryInterface.findEntry(entryid).isPublished() || (!entryInterface.findEntry(entryid).isPublished() && admin_role)) {
				entries.add(entryInterface.findEntry(entryid));
			}
		}

		return new ModelAndView("entrylist", new ModelMap().addAttribute("entries", entries));
	}

	// 查询标签列表
	@ModelAttribute("tagList")
	public Collection<Tag> populateTags() {
		return tagInterface.findTagEntities();
	}

	// 生成登录密码
	public static void main(String[] args) {
		ShaPasswordEncoder sha = new ShaPasswordEncoder();
		sha.setEncodeHashAsBase64(false);
		String pwd = sha.encodePassword("admin", null);
		System.out.println("哈希算法 256: " + pwd);
	}

}
